#!/usr/bin/env python2.5

##############################################################################################
#
#    LocateME! - Finds location of user in a specific building using contextual information
#    Copyright (C) <2009>  <Kattie Tay>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>
#
##############################################################################################


# Import packages
import pygtk
pygtk.require('2.0')
import gtk
import hildon
import pango
import webbrowser
import time
import re
import main_GUI
import gps_funcs
import wlan_funcs
import db_funcs


# Initialize global variables
rloc_name = ""
results_window = 0
loc_essid = ""
curr_iap_list = []
curr_light_int = ""
 

# Open results GUI window
def show_window(loc_name):
    global rloc_name
    # Set passed in value as global variable rloc_name
    rloc_name = loc_name
    # Call function to initialize GUI
    init_resultsGUI()
    
    
# Initialize results GUI window
def init_resultsGUI():
    global rloc_name, results_window, loc_essid, curr_iap_list, curr_light_int
    
    # --- Results window ---
    # Create results window
    results_window = hildon.Window()
    results_window.connect("destroy", return_to_main_cb, None)  
    results_window.set_border_width(10)
    results_window.set_title("LocateME! Results")
     
    # Create table layout
    rtable_layout = gtk.Table(10, 10, True)
    results_window.add(rtable_layout)
    
    
    # --- Location name label ---
    # Create label to display location name
    rloc_name_label_str = "Location: %s" %rloc_name
    rloc_name_label = gtk.Label(rloc_name_label_str)
    rloc_name_label.modify_font(pango.FontDescription("Bold"))
    
    rtable_layout.attach(rloc_name_label, 1, 9, 1, 2, gtk.EXPAND, gtk.EXPAND, 5, 5)
    rloc_name_label.set_alignment(0, 0)
    rloc_name_label.show()
    
    
    # --- Scan results label ---
    # Create label to display scan results
    rscan_results_label1_str = "You are nearest to: "
    rscan_results_label1 = gtk.Label(rscan_results_label1_str)
    rtable_layout.attach(rscan_results_label1, 1, 9, 2, 3, gtk.EXPAND, gtk.EXPAND, 5, 5)
    rscan_results_label1.set_alignment(0.5, 0.5)
    rscan_results_label1.show()
    
    # Call function to get scan results
    rscan_results_label2_str, loc_essid, curr_iap_list, curr_light_int = get_scan_results()
    # Display results in window
    rscan_results_label2 = gtk.Label(rscan_results_label2_str)
    
    # Set label attributes
    rscan_results_label2_attr = pango.AttrList()
    fg_color = pango.AttrForeground(30000, 0, 30000, 0, 5000)
    size = pango.AttrSize(30000, 0, -1)
    weight = pango.AttrWeight(pango.WEIGHT_BOLD, 0, 5000)
    rscan_results_label2_attr.insert(fg_color)
    rscan_results_label2_attr.insert(size)
    rscan_results_label2_attr.insert(weight)
    rscan_results_label2.set_attributes(rscan_results_label2_attr)
    rscan_results_label2.set_alignment(0.5, 0.5)
        
    rtable_layout.attach(rscan_results_label2, 1, 9, 3, 5, gtk.FILL, gtk.EXPAND, 5, 5)
    rscan_results_label2.show()


    # --- Details of current point button ---
    # Create button to show details of current location
    curr_loc_details_button_str = "Details of current point"
    curr_loc_details_button = gtk.Button(curr_loc_details_button_str)
    curr_loc_details_button.connect("clicked", curr_loc_details_cb, None)
    curr_loc_details_button.set_alignment(0.5, 0.5)
    
    rtable_layout.attach(curr_loc_details_button, 1, 5, 5, 7, gtk.EXPAND, gtk.FILL, 5, 20)
    curr_loc_details_button.show()
    
    
    # --- Show location on map button ---
    # Create button to show location on map
    show_loc_on_map_button_str = "Show location on map"
    show_loc_on_map_button = gtk.Button(show_loc_on_map_button_str)
    show_loc_on_map_button.connect("clicked", show_loc_on_map_cb, None)
    show_loc_on_map_button.set_alignment(0.5, 0.5)
    
    rtable_layout.attach(show_loc_on_map_button, 5, 9, 5, 7, gtk.EXPAND, gtk.FILL, 5, 20)
    show_loc_on_map_button.show()
    
    
    # --- Edit Data button --- 
    # Create button to edit data
    redit_data_button_str = "Edit Data"
    redit_data_button = gtk.Button(redit_data_button_str)
    redit_data_button.connect("clicked", edit_data_cb, None)
    redit_data_button.set_alignment(0.5, 0.5)
    
    # Set button label attributes
    redit_data_label = redit_data_button.child
    redit_data_label.modify_font(pango.FontDescription("Bold"))
    
    rtable_layout.attach(redit_data_button, 0, 3, 7, 10, gtk.FILL, gtk.FILL, 10, 20)
    redit_data_button.show()
    
    
    # --- RelocateME button ---   
    # Create button to re-run scan to find location of user
    relocateme_button_str = "Re-LocateME!"
    relocateme_button = gtk.Button(relocateme_button_str)
    relocateme_button.connect("clicked", relocateme_cb, rscan_results_label2)
    relocateme_button.set_alignment(0.5, 0.5)
    
    # Set button label attributes
    relocateme_label = relocateme_button.child
    relocateme_label.modify_font(pango.FontDescription("Bold 24"))
        
    rtable_layout.attach(relocateme_button, 3, 7, 7, 10, gtk.FILL, gtk.FILL, 10, 20)
    relocateme_button.show()

    
    # --- Return to Main button ---
    # Create button to return user to main screen
    return_to_main_button_str = "Return to Main"
    return_to_main_button = gtk.Button(return_to_main_button_str)
    return_to_main_button.connect("clicked", destroy_cb, None)
    return_to_main_button.set_alignment(0.5, 0.5)
    
    # Set button label attributes
    return_to_main_label = return_to_main_button.child
    return_to_main_label.modify_font(pango.FontDescription("Bold"))
        
    rtable_layout.attach(return_to_main_button, 7, 10, 7, 10, gtk.FILL, gtk.FILL, 10, 20)
    return_to_main_button.show()

    
    # --- Menu ---
    # Set up the menu bar
    roptions_menu = gtk.Menu()
    # Create menu items
    relocateme_menuitem = gtk.MenuItem("Re-LocateME!")
    return_to_main_menuitem = gtk.MenuItem("Return to Main")
    edit_data_menuitem = gtk.MenuItem("Edit Data")
    exit_menuitem = gtk.MenuItem("Exit")
                        
    roptions_menu.append(relocateme_menuitem)
    roptions_menu.append(return_to_main_menuitem)
    roptions_menu.append(edit_data_menuitem)
    roptions_menu.append(exit_menuitem)

    relocateme_menuitem.connect("activate", relocateme_cb, rscan_results_label2)
    return_to_main_menuitem.connect_object("activate", destroy_cb, None)
    edit_data_menuitem.connect_object("activate", edit_data_cb, None)
    exit_menuitem.connect_object("activate", exit_cb, None)
    
    relocateme_menuitem.show()
    return_to_main_menuitem.show()
    edit_data_menuitem.show()
    exit_menuitem.show()
    
    results_window.set_menu(roptions_menu)
    
    
    # Show results window
    results_window.show_all()
    
        
# Callback function for Details button
def curr_loc_details_cb(widget, data=None):
    global results_window, loc_essid, curr_iap_list, curr_light_int
    # Create result details dialog window
    details_dialog = gtk.Dialog("Result Details", results_window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, 
                                                                                     gtk.RESPONSE_CANCEL))
    details_dialog.set_size_request(320, 250)
    # Display essid, light intensity and iap addr with sig strength in window
    details_dialog_label_str = "ESSID: %s\nLight intensity: %s\nIAP list:\n" %(loc_essid, curr_light_int)
    
    for i in range(0, len(curr_iap_list)):
        details_dialog_label_str = details_dialog_label_str + curr_iap_list[i][0] + "\t" + curr_iap_list[i][1] + " dBm\n"
        
    details_dialog_label = gtk.Label(details_dialog_label_str)
    details_dialog_label.set_line_wrap(True)
    scroll_window = gtk.ScrolledWindow()
    scroll_window.add_with_viewport(details_dialog_label)
    details_dialog.vbox.pack_start(scroll_window, True, True, 0)
    details_dialog_label.show()
    scroll_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    scroll_window.show()

    # Run result details dialog window
    result = details_dialog.run()
    # Destroy result details dialog window when Cancel is pressed
    if result == gtk.RESPONSE_CANCEL:
        details_dialog.destroy()


# Callback function for Show Location On Map button
def show_loc_on_map_cb(widget, data=None):
    global rloc_name
    # Get connection status
    connected = wlan_funcs.wlan_check_conn_status()
    if not connected:
        # Display error message
        get_no_conn_dialog()
    else:
        # Get corresponding geocode value of location
        geocode = db_funcs.db_get_loc_geocode(rloc_name)
        # Call function to get url of map
        map_addr = gps_funcs.gps_get_map_addr(geocode)
        # Open url in new browser window
        webbrowser.open_new(map_addr)
    
    
# Callback function for ReLocateMe button and menu item
def relocateme_cb(widget, rscan_results_label2):
    global loc_essid, curr_iap_list, curr_light_int
    # Get connection status
    connected = wlan_funcs.wlan_check_conn_status()
    if not connected:
        # Display error message
        get_no_conn_dialog()
    else:
        # Call function to get scan results
        loc_desc, loc_essid, curr_iap_list, curr_light_int = get_scan_results()
        # Update results window with description of current position
        rscan_results_label2.set_text(loc_desc)


# Callback function for closing window and re-opening main window
def return_to_main_cb(widget, data=None):
    global results_window
    # Destroy current window
    results_window.destroy()
    # Re-open main window
    main_GUI.mainGUI()


# Callback function to destroy window
def destroy_cb(widget, data=None):
    global results_window
    # Destroy results window
    results_window.destroy()


# Callback function for Edit Data button and menu item
def edit_data_cb(widget, data=None):
    global results_window, rloc_name, loc_essid
    # Create edit scan pts dialog window
    edit_data_dialog = gtk.Dialog("List of Scan Points", results_window, gtk.DIALOG_MODAL,
                                  ("Add", gtk.RESPONSE_APPLY, "Edit", gtk.RESPONSE_OK, "Delete", 
                                   gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
    edit_data_dialog.set_size_request(480, 250)
    # Create list within edit scan pts dialog window
    desc_liststore = gtk.ListStore(str)
    # Get list of all descriptions corresponding to rloc_name and display 
    desc_list = db_funcs.db_get_loc_desc_list(rloc_name)
    for i in range(0, len(desc_list)):
        desc_liststore.append(['%s' %desc_list[i]])
    desc_listview = gtk.TreeView(desc_liststore)
    desc_column = gtk.TreeViewColumn('Description')
    desc_listview.append_column(desc_column)
    desc_cell = gtk.CellRendererText()
    desc_column.pack_start(desc_cell, True)
    desc_column.add_attribute(desc_cell, 'text', 0)

    desc_listsel = desc_listview.get_selection()
    # Allow only one value to be selected at any given time
    desc_listsel.set_mode(gtk.SELECTION_SINGLE)
    
    # Create scrolled window
    scroll_window = gtk.ScrolledWindow()
    scroll_window.add(desc_listview)

    edit_data_dialog.vbox.pack_start(scroll_window, True, True, 0)
    scroll_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    desc_listview.show()
    scroll_window.show()
    
    while True:
        # Run edit scan pts dialog window
        desc_list_result = edit_data_dialog.run()
        # Exit infinite loop whee Cancel is pressed
        if desc_list_result == gtk.RESPONSE_CANCEL:
            break
        # Display add data window when Add Data is pressed
        elif desc_list_result == gtk.RESPONSE_APPLY:
            # Call function to display add data window
            add_new_desc = get_add_edit_dialog(None, "Add Data")
            # If valid value is returned, add desc to list
            if not add_new_desc == None:
                desc_liststore.append(['%s' %add_new_desc])   
        # Display edit data window when Edit Data is pressed         
        elif desc_list_result == gtk.RESPONSE_OK:
            # Get selection
            (model, iter) = desc_listsel.get_selected()
            # If none selected
            if iter == None:
                # Display error message
                get_none_sel_dialog()
            else:
                # Get selected value
                desc = model.get_value(iter, 0)
                # Call function to display edit data window
                get_add_edit_dialog(desc, "Edit Data")
        # Delete selected value when Delete is pressed
        elif desc_list_result == gtk.RESPONSE_ACCEPT:
            # Get selection
            (model, iter) = desc_listsel.get_selected()
            # If none selected
            if iter == None:
                # Display error message
                get_none_sel_dialog()
            else:
                # Create delete confirmation dialog window
                confirm_del_dialog = gtk.Dialog("Delete?", results_window, gtk.DIALOG_MODAL, (gtk.STOCK_YES, gtk.RESPONSE_YES,
                                                                                              gtk.STOCK_NO, gtk.RESPONSE_NO))
                confirm_del_dialog_label = gtk.Label("Are you sure you want to delete this?")
                confirm_del_dialog.vbox.pack_start(confirm_del_dialog_label, True, True, 0)
                confirm_del_dialog.set_has_separator(False)
                confirm_del_dialog.show_all()
                
                # Run delete confirmation dialog window
                confirm_del_result = confirm_del_dialog.run()
                # Remove selected value from db and list when Yes is pressed
                if confirm_del_result == gtk.RESPONSE_YES:
                    # Remove selected value from db
                    db_funcs.db_remove_desc(model.get_value(iter, 0))
                    # Remove selected value from list
                    model.remove(iter)
                    # Destroy delete confirmation dialog window
                    confirm_del_dialog.destroy()
                # Destroy delete confirmation dialog window when No is pressed
                elif confirm_del_result == gtk.RESPONSE_NO:
                    confirm_del_dialog.destroy()
    
    # Destroy edit scan pts dialog window
    edit_data_dialog.destroy()
                    

# Callback function for Exit menu item
def exit_cb(widget, data=None):
    # Exit application
    gtk.main_quit()


# Get add or edit dialog box
def get_add_edit_dialog(desc, type):
    global rloc_name, results_window, loc_essid
    # Create add or edit data dialog window
    add_edit_dialog = gtk.Dialog(type, results_window, gtk.DIALOG_MODAL, ("Scan", gtk.RESPONSE_ACCEPT, "Save", 
                                                                             gtk.RESPONSE_OK, gtk.STOCK_CANCEL, 
                                                                             gtk.RESPONSE_CANCEL))
    add_edit_dialog.set_size_request(350, 250)
    
    if type == "Add Data":
        # Create an entry text field for users to enter description
        add_entry_label = gtk.Label("Description: ")
        add_edit_dialog.vbox.pack_start(add_entry_label, True, True, 5)
        add_entry_label.set_alignment(0, 0.5)
        add_entry_label.show()
        add_entry = gtk.Entry()
        add_edit_dialog.vbox.pack_start(add_entry, True, True, 5)
        add_entry.show()
        add_edit_dialog_label_str = ""
    elif type == "Edit Data":
        # Get details of scan pt corresponding to rloc_name and desc
        desc_iap_list, desc_light_int = db_funcs.db_get_desc_details(rloc_name, desc)
        add_edit_dialog_label1_str = "ESSID: %s\nLight intensity: %s\nIAP list:\n" %(loc_essid, desc_light_int)
        add_edit_dialog_label2_str = ""
        for i in range(0, len(desc_iap_list)):
            add_edit_dialog_label2_str = add_edit_dialog_label2_str + desc_iap_list[i][0] + "\t" + desc_iap_list[i][1] + " dBm\n"
            
        add_edit_dialog_label_str = add_edit_dialog_label1_str + add_edit_dialog_label2_str
        
    add_edit_dialog_label = gtk.Label(add_edit_dialog_label_str)
    add_edit_dialog_label.set_line_wrap(True)
    scroll_window = gtk.ScrolledWindow()
    scroll_window.add_with_viewport(add_edit_dialog_label)
    add_edit_dialog.vbox.pack_start(scroll_window, True, True, 0)
    add_edit_dialog_label.show()
    scroll_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    scroll_window.show()
    # Disable Save button
    add_edit_dialog.set_response_sensitive(gtk.RESPONSE_OK, False)
    
    while True:
        # Run add or edit data dialog window
        add_edit_result = add_edit_dialog.run()
        # Exit infinite loop when Cancel is pressed
        if add_edit_result == gtk.RESPONSE_CANCEL:
            break
        # Scan for new data when Scan is pressed
        elif add_edit_result == gtk.RESPONSE_ACCEPT:
            # Get connection status
            connected = wlan_funcs.wlan_check_conn_status()
            if not connected:
                # Display error message
                get_no_conn_dialog()
            else:
                # Get new wlan data
                new_desc_iap_list = wlan_funcs.wlan_get_iap_stats(loc_essid)
                # Get new light intensity data
                new_desc_light_int = get_light_intensity()
                add_edit_dialog_label1_str = "ESSID: %s\nLight intensity: %s\nIAP list:\n" %(loc_essid, new_desc_light_int)
                add_edit_dialog_label2_str = ""
                for i in range(0, len(new_desc_iap_list)):
                    add_edit_dialog_label2_str = add_edit_dialog_label2_str + new_desc_iap_list[i][0] + "\t" + new_desc_iap_list[i][1] + " dBm\n"
                 
                add_edit_dialog_label_str = add_edit_dialog_label1_str + add_edit_dialog_label2_str
                add_edit_dialog_label.set_text(add_edit_dialog_label_str)
                # Enable Save button
                add_edit_dialog.set_response_sensitive(gtk.RESPONSE_OK, True)
        # Save values when Save is pressed
        elif add_edit_result == gtk.RESPONSE_OK:
            if type == "Add Data":
                # Get description entered in entry field
                add_new_desc = add_entry.get_text()
                add_new_desc = add_new_desc.strip()
                if add_new_desc == "":
                    # Create empty field dialog window
                    empty_field_dialog = gtk.Dialog("Error!", results_window, gtk.DIALOG_MODAL, 
                                                         (gtk.STOCK_OK, gtk.RESPONSE_OK))
                    empty_field_dialog_label = gtk.Label("Please enter a description for this scan point.")
                    empty_field_dialog.vbox.pack_start(empty_field_dialog_label, True, True, 0)
                    empty_field_dialog.set_has_separator(False)
                    empty_field_dialog.show_all()
                    # Run empty field dialog window
                    emptyfield_result = empty_field_dialog.run()
                    # Destroy empty field dialog window when OK is pressed
                    if emptyfield_result == gtk.RESPONSE_OK:
                        empty_field_dialog.destroy()
                else:
                    # Check if description exists
                    exists = 0
                    desc_list = db_funcs.db_get_loc_desc_list(rloc_name)
                    for i in range(0, len(desc_list)):
                        match = re.match(add_new_desc, desc_list[i])
                        # If description exists
                        if match:
                            exists = 1
                            # Create description exists dialog window
                            desc_exists_dialog = gtk.Dialog("Error!", results_window, gtk.DIALOG_MODAL, 
                                                         (gtk.STOCK_OK, gtk.RESPONSE_OK))
                            desc_exists_dialog_label = gtk.Label("The description entered already exists.\nPlease enter a new description.")
                            desc_exists_dialog_label.set_line_wrap(True)
                            desc_exists_dialog.vbox.pack_start(desc_exists_dialog_label, True, True, 0)
                            desc_exists_dialog.set_has_separator(False)
                            desc_exists_dialog.show_all()
                            # Run description exists dialog window
                            desc_exists_result = desc_exists_dialog.run()
                            # Destroy description exists dialog window when OK is pressed
                            if desc_exists_result == gtk.RESPONSE_OK:
                                desc_exists_dialog.destroy()
                                # Exit for loop
                                break
                    if not exists:
                        # Add new scan pt to db
                        db_funcs.db_add_new_scanpt(rloc_name, add_new_desc, new_desc_iap_list, new_desc_light_int)
                        # Destroy add or edit dialog window
                        add_edit_dialog.destroy()
                        # Return name of new desc
                        return add_new_desc
            elif type == "Edit Data":
                # Update scan pts data corresponding to rloc_name and desc
                db_funcs.db_edit_scanpt_details(rloc_name, desc, new_desc_iap_list, new_desc_light_int)
                # Disable Save button
                add_edit_dialog.set_response_sensitive(gtk.RESPONSE_OK, False)
    # Destroy add or edit dialog window 
    add_edit_dialog.destroy()
                

# Get no value selected dialog box
def get_none_sel_dialog():
    global results_window
    # Create no value selected dialog window
    none_sel_dialog = gtk.Dialog("Error!", results_window, gtk.DIALOG_MODAL, (gtk.STOCK_OK, gtk.RESPONSE_OK))
    none_sel_dialog_label = gtk.Label("No value selected!")
    none_sel_dialog.vbox.pack_start(none_sel_dialog_label, True, True, 0)
    none_sel_dialog.set_has_separator(False)
    none_sel_dialog.show_all()
    
    # Run no value selected dialog window
    none_sel_dialog_result = none_sel_dialog.run()
    # Destroy no value selected dialog window when OK is pressed
    if none_sel_dialog_result == gtk.RESPONSE_OK:
        none_sel_dialog.destroy()


# Get no internet connection dialog box
def get_no_conn_dialog():
    global results_window
    # Create no connection dialog window
    no_conn_dialog = gtk.Dialog("No internet connection!", results_window, gtk.DIALOG_MODAL, (gtk.STOCK_OK,
                                         gtk.RESPONSE_OK))
    no_conn_dialog_label = gtk.Label("Internet connection is required to proceed. Please connect to the internet.")
    no_conn_dialog_label.set_line_wrap(True)
    no_conn_dialog.vbox.pack_start(no_conn_dialog_label, True, True, 0)
    no_conn_dialog_label.show()
    no_conn_dialog.set_has_separator(False)
    
    # Run no connection dialog window
    noconn_result = no_conn_dialog.run()
    # Destroy no connection dialog window when OK is pressed
    if noconn_result == gtk.RESPONSE_OK:
        no_conn_dialog.destroy()


# Get scan results
def get_scan_results():
    global rloc_name, loc_essid, curr_iap_list, curr_light_int
    # Get essid corresponding to rloc_name
    loc_essid = db_funcs.db_get_loc_essid(rloc_name)
    # Perform wlan scan at current point
    curr_iap_list = wlan_funcs.wlan_get_iap_stats(loc_essid)
    # Get light intensity at current point
    curr_light_int = get_light_intensity()
    
    # Get list of all scan pts data corresponding to rloc_name
    loc_all_iap_list, loc_light_int_list = db_funcs.db_get_loc_iap_lightint_list(rloc_name)
    # Get list of all descriptions corresponding to rloc_name
    loc_all_desc_list = db_funcs.db_get_loc_desc_list(rloc_name)
    
    # Algorithm for finding location
    # If description list is empty
    if len(loc_all_desc_list) == 0:
        closest_desc = "No scan points available!"
    else:
        mse_list = []
        mse_idx = []
        # Loop through each row in loc_all_iap_list
        for i in range(0, len(loc_all_iap_list)):
            # Extract current row
            one_iap_list = loc_all_iap_list[i]
            mse_sigstrength = 0
            total_sq_err_sigstrength = 0
            count = 0
            print one_iap_list

            # Loop through each iap in curr_iap_list
            for j in range(0, len(curr_iap_list)):
                # Compare it with each row in one_iap_list until match is found
                for k in range(0, len(one_iap_list)):
                    # If match
                    if curr_iap_list[j][0] in one_iap_list[k][0]:
                        # Get difference in signal strength
                        err_sigstrength = int(curr_iap_list[j][1]) - int(one_iap_list[k][1])
#                        print "err ss: %i" %err_sigstrength
                        # Square the error value
                        sq_err_sigstrength = err_sigstrength * err_sigstrength
                        print "sq_err ss: %i" %sq_err_sigstrength
                        # Add this squared error with the rest of the squared errors
                        total_sq_err_sigstrength = total_sq_err_sigstrength + sq_err_sigstrength
                        # Keeps track of number of matches
                        count = count + 1
                        print "cnt: %i" %count
                        # After a match is found, break out of this for loop
                        break
                    
            # If there was at least 1 match
            if not count == 0:
#                # Get mse of sig strength
#                mse_sigstrength = total_sq_err_sigstrength / count
#                print "mse ss: %i" %mse_sigstrength 
                # Get difference in light int
                err_lightint = int(curr_light_int) - int(loc_light_int_list[i])
#                print "err li: %i" %err_lightint
                # Square the error value
                sq_err_lightint = err_lightint * err_lightint
                print "sq_err li: %i" %sq_err_lightint
                # Get total mse 
#                total_mse = (mse_sigstrength + sq_err_lightint) / 2
                total_mse = (total_sq_err_sigstrength + sq_err_lightint) / (count+1)
                print "tot mse: %i" %total_mse
                # Add this to mse_list
                mse_list.append(total_mse)
                # Use mse_idx to keep track of which mse belongs to which description
                mse_idx.append(i)
        
        print "mse_list = %s" %mse_list
        # If mse_list is empty    
        if len(mse_list) == 0:
            closest_desc = "No matches found!"
        else:
            # Get the min value in the list
            min_mse = min(mse_list)
            print "min mse: %i" %min_mse
            # Get the index corresponding to the min value
            min_index = mse_list.index(min_mse)
            print "min idx: %i" %min_index
            index = mse_idx[min_index]
            print "idx: %i" %index
            # Retrieve description which has lowest mse i.e. closest to current point
            closest_desc = loc_all_desc_list[index]
    return closest_desc, loc_essid, curr_iap_list, curr_light_int


# Get light intensity
def get_light_intensity():
    # Open file containing light intensity data
    f = open('/sys/bus/i2c/devices/0-0029/lux', 'r')
    # If file exists
    if f:
        # Read light intensity value 
        light_int = f.read()
        # Close file
        f.close()
    # Return light intensity value
    return light_int.strip()

    
    



